package org.ehe.business.monitor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.ehe.business.overdue.domain.OverdueRecord;
import org.ehe.business.overdue.mapper.OverdueRecordMapper;
import org.ehe.business.overdue.queue.RedisDelayQueue;
import org.ehe.business.timeout.service.SsePushMessageService;
import org.ehe.business.timeout.service.TimeoutInstanceService;
import org.ehe.common.core.service.WorkflowService;
import org.ehe.common.core.utils.SpringContextUtils;
import org.ehe.erp.enums.ErpAuditStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Date;


/**
 * @author :zhangnn
 * @className :MethodMonitorAspect
 * @description: TODO
 * @date 2025-10-13 13:43:26
 */
@Slf4j
@Aspect
@Component
public class MethodMonitorAspect {

    @Autowired
    private OverdueRecordMapper overdueRecordMapper;
    @Autowired
    private RedisDelayQueue delayQueue;
    @Autowired
    private TimeoutInstanceService timeoutInstanceService;
    @Autowired
    private WorkflowService workflowService;



    // 切点：拦截所有@MonitorMethod注解的方法
    @Pointcut("@annotation(monitorMethod)")
    public void pointcut(MonitorMethod monitorMethod) {}

    // 后置通知：方法执行后处理
    @AfterReturning(pointcut = "pointcut(monitorMethod)", returning = "result")
    public void afterReturning(JoinPoint joinPoint, MonitorMethod monitorMethod, Object result) {
        try {
            // 1. 获取数据提取器（通过注解指定的类实例化）
            Class<? extends DataExtractor> extractorClass = monitorMethod.extractor();
            DataExtractor extractor = SpringContextUtils.getBean(extractorClass); // 从Spring容器获取Bean
            if (extractor == null) {
                log.error("未找到数据提取器：{}", extractorClass.getName());
                return;
            }

            // 2. 提取业务数据
            MonitorData monitorData = extractor.extract(joinPoint, result);
            if(null == monitorData.getCreateTime()){
                monitorData.setCreateTime(LocalDateTime.now());
            }
            if (monitorData == null || monitorData.getBizId() == null) {
                log.warn("业务数据提取失败，bizType：{}", monitorMethod.bizType());
                return;
            }
            //已提交
            String status = monitorData.getStatus();
            if (status.equals(ErpAuditStatus.SUBMITTED.getStatus().toString()) || status.equals(ErpAuditStatus.APPROVE.getStatus().toString())) {
                //修改超期信息
                overdueRecordMapper.updateHandleStatus(monitorMethod.bizType(), monitorData.getBizId(), 1);
                //取消超期提醒
                // 2. 从延迟队列移除任务
                delayQueue.removeTask(monitorMethod.bizType(), monitorData.getBizId());
                delayQueue.removeRemindTask(monitorMethod.bizType(), monitorData.getBizId());

                //已审核的需要增加任务时效监听
                String businessStatus = workflowService.getBusinessStatus(String.valueOf(monitorData.getBizId()),null);
                if(businessStatus.equals("finish")){
                    timeoutInstanceService.saveOrUpdateMonitor(monitorMethod,monitorData);
                }
            } else {

                // 3. 计算截止时间（创建时间+1小时）
                LocalDateTime deadlineTime = monitorData.getCreateTime().plusHours(1);

                // 4. 构建入库实体（通用逻辑）
                OverdueRecord record = new OverdueRecord();
                record.setBizType(monitorMethod.bizType());
                record.setBizId(monitorData.getBizId());
                record.setBizName(monitorData.getBizName());
                record.setDeadlineTime(deadlineTime);
                //提前30分钟
                record.setRemindTime(record.getDeadlineTime().minusMinutes(30));
                record.setHandleStatus(0); // 未处理
                record.setCreateBy(monitorData.getCreateBy());
                record.setTenantId(monitorData.getTenantId());
                record.setDelFlag("0");

                // 5. 插入或更新（利用唯一索引）
                OverdueRecord existing = overdueRecordMapper.selectByBizTypeAndId(
                    monitorMethod.bizType(), monitorData.getBizId()
                );
                if (existing != null) {
                    if(monitorData.getStatus().equals(ErpAuditStatus.SUBMITTED.getStatus().toString())){
                       if(existing.getDeadlineTime().compareTo(LocalDateTime.now()) < 0){
                           existing.setHandleStatus(4); //超期处理
                       } else {
                           existing.setHandleStatus(1);
                       }
                    }
                    existing.setDeadlineTime(existing.getDeadlineTime());
                    //被拒绝，重新计算提醒时间
                    if(monitorData.getStatus().equals(ErpAuditStatus.REJECTED.getStatus().toString()) ||
                        monitorData.getStatus().equals(ErpAuditStatus.WAITING.getStatus().toString())){
                        existing.setHandleStatus(0);
                        existing.setDeadlineTime(LocalDateTime.now().plusHours(1));
                        existing.setRemindTime(existing.getDeadlineTime().minusMinutes(30));
                        existing.setRemark("驳回");
                        if(monitorData.getStatus().equals(ErpAuditStatus.WAITING.getStatus().toString())){
                            existing.setRemark("等待负责人响应");
                        }
                        // 删掉之前任务
                        delayQueue.removeTask(monitorMethod.bizType(), monitorData.getBizId());
                        delayQueue.removeRemindTask(monitorMethod.bizType(), monitorData.getBizId());

                        //重新加入
                        delayQueue.addTask(record.getBizType(), record.getBizId(), record.getDeadlineTime());
                        delayQueue.addRemindTask(record.getBizType(), record.getBizId(), record.getRemindTime());
                    }
                    existing.setUpdateTime(new Date());
                    overdueRecordMapper.updateById(existing);
                } else {
                    record.setCreateTime(new Date());
                    overdueRecordMapper.insert(record);

                    delayQueue.addTask(record.getBizType(), record.getBizId(), record.getDeadlineTime());
                    delayQueue.addRemindTask(record.getBizType(), record.getBizId(), record.getRemindTime());
                }

            }
        } catch (Exception e) {
            log.error("监听处理失败，bizType：{}", monitorMethod.bizType(), e);
        }
    }
}
